"use strict";

let sendClientRequestCallback = null;

// 事件处理对象
var EventUtil = {

    // 对象按照键名来进行排序
    sortByKey: function (obj) {
        const newKey = Object.keys(obj).sort().reverse();
        let newObj = {};//创建一个新的对象，用于存放排好序的键值对
        for (let i = 0; i < newKey.length; i++) {//遍历newkey数组
            newObj[newKey[i]] = obj[newKey[i]];//向新创建的对象中按照排好的顺序依次增加键值对
        }
        return newObj;
    },

    /**
     * 浏览器获取终端版本
     * */
    browser: {
        versions: function () {

            let u = navigator.userAgent,

                app = navigator.appVersion;

            return {

                trident: u.indexOf('Trident') > -1,                        /*IE内核*/

                presto: u.indexOf('Presto') > -1,          /*opera内核*/

                webKit: u.indexOf('AppleWebKit') > -1, /*苹果、谷歌内核*/

                gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1,        /*火狐内核*/

                mobile: !!u.match(/AppleWebKit.*Mobile.*/),        /*是否为移动终端*/

                ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), /*ios终端*/

                android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, /*android终端或者uc浏览器*/

                iPhone: u.indexOf('iPhone') > -1,          /*是否为iPhone或者QQHD浏览器*/

                iPad: u.indexOf('iPad') > -1,      /*是否iPad*/

                webApp: u.indexOf('Safari') == -1,          /*是否web应该程序，没有头部与底部*/

                souyue: u.indexOf('souyue') > -1,

                superapp: u.indexOf('superapp') > -1,

                weixin: u.toLowerCase().indexOf('micromessenger') > -1,

                Safari: u.indexOf('Safari') > -1

            };

        }(),

        language: (navigator.browserLanguage || navigator.language).toLowerCase()
    },
    /**
     * 时间转换刚刚/过去格式
     * */
    timestampFormat: function (timestamp) {
        function zeroize(num) {
            return (String(num).length == 1 ? '0' : '') + num;
        }

        let curTimestamp = parseInt(new Date().getTime() / 1000); //当前时间戳
        let timestampDiff = curTimestamp - timestamp; // 参数时间戳与当前时间戳相差秒数

        let curDate = new Date(curTimestamp * 1000); // 当前时间日期对象
        let tmDate = new Date(timestamp * 1000);  // 参数时间戳转换成的日期对象

        let Y = tmDate.getFullYear(), m = tmDate.getMonth() + 1, d = tmDate.getDate();
        let H = tmDate.getHours(), i = tmDate.getMinutes(), s = tmDate.getSeconds();

        if (timestampDiff < 60) { // 一分钟以内
            return "刚刚";
        } else if (timestampDiff < 3600) { // 一小时前之内
            return Math.floor(timestampDiff / 60) + "分钟前";
        } else if (curDate.getFullYear() == Y && curDate.getMonth() + 1 == m && curDate.getDate() == d) {
            return '今天' + zeroize(H) + ':' + zeroize(i);
        } else {
            var newDate = new Date((curTimestamp - 86400) * 1000); // 参数中的时间戳加一天转换成的日期对象
            if (newDate.getFullYear() == Y && newDate.getMonth() + 1 == m && newDate.getDate() == d) {
                return '昨天' + zeroize(H) + ':' + zeroize(i);
            } else if (curDate.getFullYear() == Y) {
                return zeroize(m) + '月' + zeroize(d) + '日 ' + zeroize(H) + ':' + zeroize(i);
            } else {
                return Y + '年' + zeroize(m) + '月' + zeroize(d) + '日 ' + zeroize(H) + ':' + zeroize(i);
            }
        }
    },

    /**
     * 生日计算年龄
     * */
    birthdayAge: function (birthday) {
        if (birthday === null) {
            return 0;
        }

        birthday = birthday.toString();
        birthday = birthday * 1000;

        //出生时间 毫秒
        let birthDayTime = new Date(birthday).getTime();

        //当前时间 毫秒
        let nowTime = new Date().getTime();

        //一年毫秒数(365 * 86400000 = 31536000000)
        return Math.floor((nowTime - birthDayTime) / 31536000000);
    },

    // 当前时间戳
    timestamp: function () {
        return parseInt(new Date().getTime() / 1000);
    },

    // 获取请求参数
    getRequestParams: function () {
        let url = location.search; //获取url中"?"符后的字串
        let thisRequestParams = new Object();
        if (url.indexOf("?") !== -1) {
            let str = url.substr(1);
            let strs = str.split("&");
            for (let i = 0; i < strs.length; i++) {
                thisRequestParams[strs[i].split("=")[0]] = $.trim(unescape(decodeURI(strs[i].split("=")[1])));
            }
        }
        return thisRequestParams;
    },
    // 时间戳转换日期格式
    getLocalTime: function (nS) {
        nS = nS.toString();

        //时间戳为10位需*1000，时间戳为13位的话不需乘1000
        if (nS.length === 10) {
            nS = nS * 1000;
        }
        let date = new Date(nS);
        let Y = date.getFullYear() + '-';

        let M = date.getMonth();
        M = (M + 1 < 10 ? '0' + (M + 1) : M + 1) + '-';

        let D = date.getDate();
        D = (D < 10 ? '0' + D : D) + ' ';

        let h = date.getHours();
        h = (h < 10 ? '0' + h : h) + ':';


        let m = date.getMinutes();
        m = (m < 10 ? '0' + m : m) + ':';

        let s = date.getSeconds();
        s = s < 10 ? '0' + s : s;

        return Y + M + D + h + m + s;

        //return new Date(parseInt(nS) * 1000).toLocaleString().replace('/g', "-").replace(/日/g, " ");
    },
    /**
     * 获取当前时间
     *          format=1 精确到天
     *          format=2 精确到分
     * */
    getCurrentDate: function (format) {
        let now = new Date();

        let year = now.getFullYear(); //得到年份
        let month = now.getMonth();//得到月份
        let date = now.getDate();//得到日期
        let day = now.getDay();//得到周几
        let hour = now.getHours();//得到小时
        let minu = now.getMinutes();//得到分钟
        let sec = now.getSeconds();//得到秒

        month = month + 1;
        if (month < 10) month = "0" + month;
        if (date < 10) date = "0" + date;
        if (hour < 10) hour = "0" + hour;
        if (minu < 10) minu = "0" + minu;
        if (sec < 10) sec = "0" + sec;

        let time = "";

        //精确到天
        if (format === 1) {
            time = year + "-" + month + "-" + date;
        }
        //精确到分
        else if (format === 2) {
            time = year + "-" + month + "-" + date + " " + hour + ":" + minu + ":" + sec;
        }

        return time;
    },

    /**
     * 获取每月的天数
     *              year 年
     *              month 月
     */
    mGetDate: function (year, month) {
        let d = new Date(year, month, 0);
        return d.getDate();
    },

    // 添加事件监听
    addEvent: function (element, type, callback) {
        if (element.addEventListener) {
            element.addEventListener(type, callback, false);
        } else if (element.attachEvent) {
            element.attachEvent('on' + type, callback);
        } else {
            element['on' + type] = callback;
        }
    },

    // 移除事件监听
    remove: function (element, type, callback) {

        if (element.removeEventListener) {
            element.removeEventListener(type, callback, false);
        } else if (element.detachEvent) {
            element.detachEvent('on' + type, callback);
        } else {
            element['on' + type] = null;
        }

    },

    // 跨浏览器获取 event 对象
    getEvent: function (event) {

        return event ? event : window.event;
    },

    // 阻止事件的默认行为
    preventDefault: function (event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    /*
     * 判断object是否空，未定义或null
     * @param object
     * @return
     */
    objectIsNull: function (obj) {
        if (obj == "" || typeof (obj) == "undefined" || obj == null) {
            return true;
        } else {
            return false;
        }
    },

    /*
     * 正则验证
     * @param s 验证字符串
     * @param type 验证类型 money,china,mobile等
     * @return
     */
    regValidate: function (s, type) {
        let objbool = false;
        let objexp = "";
        switch (type) {
            case 'money': //金额格式,格式定义为带小数的正数，小数点后最多三位
                objexp = "^[0-9]+[\.][0-9]{0,3}$";
                break;
            case 'numletter_': //英文字母和数字和下划线组成
                objexp = "^[0-9a-zA-Z\_]+$";
                break;
            case 'numletter': //英文字母和数字组成
                objexp = "^[0-9a-zA-Z]+$";
                break;
            case 'numletterchina': //汉字、字母、数字组成
                objexp = "^[0-9a-zA-Z\u4e00-\u9fa5]+$";
                break;
            case 'email': //邮件地址格式
                objexp = "^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$";
                break;
            case 'tel': //固话格式
                objexp = /^((\d2,3)|(\d{3}\-))?(0\d2,3|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/;
                break;
            case 'mobile': //手机号码
                objexp = /^1\d{10}$/;
                break;
            case 'decimal': //浮点数
                objexp = "^[0-9]+([.][0-9]+)?$";
                break;
            case 'url': //网址
                objexp = "(http://|https://){0,1}[\w\/\.\?\&\=]+";
                break;
            case 'date': //日期 YYYY-MM-DD格式
                objexp = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/;
                break;
            case 'int': //整数
                objexp = "^[0-9]*[1-9][0-9]*$";
                break;
            case 'int+': //正整数包含0
                objexp = "^\\d+$";
                break;
            case 'int-': //负整数包含0
                objexp = "^((-\\d+)|(0+))$";
                break;
            case 'china': //中文
                objexp = /^[\u0391-\uFFE5]+$/;
                break;
        }
        let re = new RegExp(objexp);
        if (re.test(s)) {
            return true;
        } else {
            return false;
        }
    },

    /**
     * 调用客户端请求
     * */
    sendClientRequest: function (method, url, params, callback) {
        // 判断是否为移动终端
        if (EventUtil.browser.versions.mobile) {

            sendClientRequestCallback = callback;

            // 客户端对应请求参数
            let sendData = {
                requestType: method,
                url: url,
                para: params,
                response: 'responseCallback'
            };

            if (EventUtil.browser.versions.ios && window.hasOwnProperty('webkit')) {
                window.webkit.messageHandlers.commonRequestAction.postMessage(sendData);
            } else if (EventUtil.browser.versions.android) {
                keke.commonRequestAction(JSON.stringify(sendData));
            } else {
                EventUtil.requestAjax(method, url, params, callback)
            }
        } else {
            EventUtil.requestAjax(method, url, params, callback)
        }
    },

    /**
     * 打开客户端页面
     * */
    openClientView: function (method, params) {
        // 判断是否为移动终端
        if (EventUtil.browser.versions.mobile) {
            if ($.inArray(method, ['userClicked', 'roomClicked']) >= 0) {
                if (EventUtil.browser.versions.ios && window.hasOwnProperty('webkit')) {
                    window.webkit.messageHandlers[method].postMessage(params);
                } else if (EventUtil.browser.versions.android) {
                    keke[method](JSON.stringify(params));
                }
            }
        }
    },


    /**
     * ajax
     * @param method  为post/get提交
     * @param url
     * @param params
     * @param callback 回调函数 function callBack(data)
     * @return
     */
    requestAjax: function (method, url, params, callback) {
        let request = $.ajax({
            method: method,
            url: url,
            data: params,
            // headers: {'Authorization': token},
        });

        /*request.beforeSend(function (xhr) {
            xhr.setRequestHeader('Authorization', token);
        });*/

        request.done(function (res) {
            // console.log(res)
            /*try {
                var res = JSON.parse(res);
                if (typeof res !== 'object' && !res) {
                    res = {
                        code: 1,
                        msg: '返回数据格式错误' + res,
                        data: []
                    }
                }

            } catch (e) {
                res = {
                    code: 1,
                    msg: 'error：' + res + '!!!' + e,
                    data: []
                }
            }*/

            callback(false, res);
        });

        request.fail(function (res) {
            // console.log(res)
            /*try {
                var res = JSON.parse(res);
                if (typeof res !== 'object' && !res) {
                    res = {
                        code: 1,
                        msg: '返回数据格式错误' + res,
                        data: []
                    }
                }

            } catch (e) {
                res = {
                    code: 1,
                    msg: 'error：' + res + '!!!' + e,
                    data: []
                }
            }*/

            callback(true, res);
        });

        request.always(function () {

        });
    },

    /*
     * 去除首尾空格
     * @ value  字符串
     * $.trim(value)   == value.replace(/(^\s*)|(\s*$)/g, "")
     * 去除字符串全部空格： value.replace(/\s+/g, "")
     * */
    replaceValue: function (value) {
        return value.replace(/(^\s*)|(\s*$)/g, "");
    },

    /**
     * ajaxUpload
     * @param type  为post/get提交
     * @param url
     * @param formData
     * @param callback 回调函数 function callBack(data)
     * @return
     */
    requestAjaxUpload: function (type, url, formData, callback) {
        let request = $.ajax({
            method: type,
            url: url,
            data: formData,
            processData: false, // 不处理发送的数据
            contentType: false, //不设置Content-Type请求头
            dataType: 'json',
            // headers: {'Authorization': token},
        });

        request.done(function (res) {
            callback(false, res);
        });

        request.fail(function (res) {
            callback(true, res);
        });

        request.always(function () {

        });
    },
    /**
     * JSON 代码展示 工具方法
     * */
    formatJson: function (json, options) {
        let reg = null,
            formatted = '',
            pad = 0,
            PADDING = '    '; // one can also use '\t' or a different number of spaces
        // optional settings
        options = options || {};
        // remove newline where '{' or '[' follows ':'
        options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;
        // use a space after a colon
        options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;

        // begin formatting...

        // make sure we start with the JSON as a string
        if (typeof json !== 'string') {
            json = JSON.stringify(json);
        }
        // parse and stringify in order to remove extra whitespace
        json = JSON.parse(json);
        json = JSON.stringify(json);

        // add newline before and after curly braces
        reg = /([\{\}])/g;
        json = json.replace(reg, '\r\n$1\r\n');

        // add newline before and after square brackets
        reg = /([\[\]])/g;
        json = json.replace(reg, '\r\n$1\r\n');

        // add newline after comma
        reg = /(\,)/g;
        json = json.replace(reg, '$1\r\n');

        // remove multiple newlines
        reg = /(\r\n\r\n)/g;
        json = json.replace(reg, '\r\n');

        // remove newlines before commas
        reg = /\r\n\,/g;
        json = json.replace(reg, ',');

        // optional formatting...
        if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
            reg = /\:\r\n\{/g;
            json = json.replace(reg, ':{');
            reg = /\:\r\n\[/g;
            json = json.replace(reg, ':[');
        }
        if (options.spaceAfterColon) {
            reg = /\:/g;
            json = json.replace(reg, ': ');
        }

        $.each(json.split('\r\n'), function (index, node) {
            let i = 0,
                indent = 0,
                padding = '';

            if (node.match(/\{$/) || node.match(/\[$/)) {
                indent = 1;
            } else if (node.match(/\}/) || node.match(/\]/)) {
                if (pad !== 0) {
                    pad -= 1;
                }
            } else {
                indent = 0;
            }

            for (i = 0; i < pad; i++) {
                padding += PADDING;
            }
            formatted += padding + node + '\r\n';
            pad += indent;
        });
        return formatted;
    },
    character: function (str) {
        return str.replace(/\u0000|\u0001|\u0002|\u0003|\u0004|\u0005|\u0006|\u0007|\u0008|\u0009|\u000a|\u000b|\u000c|\u000d|\u000e|\u000f|\u0010|\u0011|\u0012|\u0013|\u0014|\u0015|\u0016|\u0017|\u0018|\u0019|\u001a|\u001b|\u001c|\u001d|\u001e|\u001f|\u007F/g, "");
    },
    removeEmoji(content) {
        content = content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "");
        content = content.replace(/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g, "");
        return content.replace(/^[\ue04e-\ue50e]+$/gi, "")
    },
};

let Base64 = {
    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    encode: function (e) {
        let t = "";
        let n, r, i, s, o, u, a;
        let f = 0;
        e = Base64._utf8_encode(e);
        while (f < e.length) {
            n = e.charCodeAt(f++);
            r = e.charCodeAt(f++);
            i = e.charCodeAt(f++);
            s = n >> 2;
            o = (n & 3) << 4 | r >> 4;
            u = (r & 15) << 2 | i >> 6;
            a = i & 63;
            if (isNaN(r)) {
                u = a = 64
            } else if (isNaN(i)) {
                a = 64
            }
            t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
        }
        return t
    },
    decode: function (e) {
        let t = "";
        let n, r, i;
        let s, o, u, a;
        let f = 0;
        e = e.replace(/[^A-Za-z0-9+/=]/g, "");
        while (f < e.length) {
            s = this._keyStr.indexOf(e.charAt(f++));
            o = this._keyStr.indexOf(e.charAt(f++));
            u = this._keyStr.indexOf(e.charAt(f++));
            a = this._keyStr.indexOf(e.charAt(f++));
            n = s << 2 | o >> 4;
            r = (o & 15) << 4 | u >> 2;
            i = (u & 3) << 6 | a;
            t = t + String.fromCharCode(n);
            if (u !== 64) {
                t = t + String.fromCharCode(r)
            }
            if (a !== 64) {
                t = t + String.fromCharCode(i)
            }
        }
        t = Base64._utf8_decode(t);
        return t
    },
    _utf8_encode: function (e) {
        e = e.replace(/rn/g, "n");
        let t = "";
        for (let n = 0; n < e.length; n++) {
            let r = e.charCodeAt(n);
            if (r < 128) {
                t += String.fromCharCode(r)
            } else if (r > 127 && r < 2048) {
                t += String.fromCharCode(r >> 6 | 192);
                t += String.fromCharCode(r & 63 | 128)
            } else {
                t += String.fromCharCode(r >> 12 | 224);
                t += String.fromCharCode(r >> 6 & 63 | 128);
                t += String.fromCharCode(r & 63 | 128)
            }
        }
        return t
    },
    _utf8_decode: function (e) {
        let t = "";
        let n = 0;
        let r = 0;
        let c2 = 0;
        let c3 = 0;
        while (n < e.length) {
            r = e.charCodeAt(n);
            if (r < 128) {
                t += String.fromCharCode(r);
                n++
            } else if (r > 191 && r < 224) {
                c2 = e.charCodeAt(n + 1);
                t += String.fromCharCode((r & 31) << 6 | c2 & 63);
                n += 2
            } else {
                c2 = e.charCodeAt(n + 1);
                c3 = e.charCodeAt(n + 2);
                t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
                n += 3
            }
        }
        return t
    }
};

function Base64DecodeStr(str) {
    let result = {};

    try {
        // TODO Base64解码
        let string = Base64.decode(str);
        if (string.substr(0, 1) === '{' && string.substr(string.length - 1, 1) === '}') {
            result.code = 1;
            result.data = string;
        } else {
            result.code = 0;
            result.data = str;
        }

    } catch (e) {
        result.code = -1;
        result.data = e;
    }

    return result;
}

function responseCallback(result, type) {

    // 客户端自定义数据类型
    switch (type) {
        case 'BaseEncodeUrl':
            let words = CryptoJS.enc.Base64.parse(result);
            result = words.toString(CryptoJS.enc.Utf8);
            result = eval("(" + result + ")");
            sendClientRequestCallback(false, result);
            break;
        case 'encodeUrl':
        default:
            if (type === 'encodeUrl') {
                result = decodeURIComponent(result);
            }
            result = result.replace(/\n/g, '');
            result = EventUtil.removeEmoji(result);
            result = EventUtil.character(result);
            result = eval("(" + result + ")");
            sendClientRequestCallback(false, result);
            break;
    }
}
